﻿
using Carpool1.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace Carpool.Controllers
{
    public enum OperationTypeEnum
    {
        发布拼车信息 = 1,
        发布拼车需求 = 2,
        申请加入拼车 = 3,
        关注拼车 = 4,
        编辑拼车信息 = 5,  // 新增：编辑操作日志类型
        删除拼车信息 = 6   // 新增：删除操作日志类型
    }

    public class CarpoolController : Controller
    {
        // 改为私有只读数据库上下文，并在Dispose中释放资源
         CarpoolEntities db = new CarpoolEntities();

        public  void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        // 车主/乘客发布拼车信息页面
        [HttpGet]
        [Authorize]  // 要求登录才能访问
        public ActionResult Publish()
        {
            return View();
        }

        // 处理拼车信息发布
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]  // 防CSRF攻击
        public async Task<ActionResult> Publish(CarpoolInfo model, string identity, List<string> routeStops)
        {
            // 验证身份参数有效性
            if (!new[] { "Owner", "Passenger" }.Contains(identity))
            {
                ModelState.AddModelError("", "身份参数无效");
                return View(model);
            }

            if (ModelState.IsValid)
            {
                try
                {
                    model.PublisherID = (int)Session["UserID"];
                    model.PublishTime = DateTime.Now;
                    model.Status = 1;

                    // 行程类型处理
                    model.InfoType = identity == "Owner" ? (byte)1 : (byte)2;

                    // 途经路线处理
                    model.Route = routeStops != null ? string.Join("|", routeStops) : "";

                    // 乘客逻辑
                    if (identity == "Passenger")
                    {
                        model.Capacity = 0;
                        model.CarType = 3;
                    }

                    db.CarpoolInfo.Add(model);
                    await db.SaveChangesAsync();

                    // 记录操作日志
                    await LogOperation((int)Session["UserID"], OperationTypeEnum.发布拼车信息, $"发布拼车信息（ID：{model.InfoID}）");

                    return RedirectToAction("Index", "Home");
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "发布失败：" + ex.Message);
                }
            }
            return View(model);
        }

        // GET: 显示编辑页面（优化版）
        [HttpGet]
        [Authorize]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var carpoolInfo = db.CarpoolInfo.Find(id);
            if (carpoolInfo == null)
            {
                return HttpNotFound();
            }

            // 权限验证：仅发布者可编辑
            if (carpoolInfo.PublisherID != (int)Session["UserID"])
            {
                TempData["ErrorMessage"] = "您没有权限编辑此拼车信息";
                return RedirectToAction("Index", "Home");
            }

            return View(carpoolInfo);
        }

        // POST: 处理编辑提交（优化版）
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit(CarpoolInfo model, List<string> routeStops)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    // 验证原数据是否存在
                    var original = db.CarpoolInfo.Find(model.InfoID);
                    if (original == null)
                    {
                        return HttpNotFound();
                    }

                    // 再次验证权限
                    if (original.PublisherID != (int)Session["UserID"])
                    {
                        TempData["ErrorMessage"] = "您没有权限编辑此拼车信息";
                        return RedirectToAction("Index", "Home");
                    }

                    // 更新可编辑字段（避免直接修改model导致的安全问题）
                    original.StartCity = model.StartCity;
                    original.EndCity = model.EndCity;
                    original.DepartureTime = model.DepartureTime;
                    original.InfoType = model.InfoType;
                    original.Capacity = model.Capacity;
                    original.CarType = model.CarType;
                    original.FeeType = model.FeeType;
                    original.Fee = model.Fee;
                    original.Message = model.Message;
                    // 处理途经点更新
                    original.Route = routeStops != null ? string.Join("|", routeStops) : "";

                    db.Entry(original).State = EntityState.Modified;
                    await db.SaveChangesAsync();

                    // 记录编辑日志
                    await LogOperation((int)Session["UserID"], OperationTypeEnum.编辑拼车信息, $"编辑拼车信息（ID：{model.InfoID}）");

                    TempData["SuccessMessage"] = "编辑成功";
                    return RedirectToAction("Index", "Home");
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "编辑失败：" + ex.Message);
                }
            }
            return View(model);
        }

        // 新增：删除拼车信息
        [HttpPost]
        [Authorize]
        public async Task<ActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var carpoolInfo = db.CarpoolInfo.Find(id);
            if (carpoolInfo == null)
            {
                return HttpNotFound();
            }

            // 权限验证：仅发布者可删除
            if (carpoolInfo.PublisherID != (int)Session["UserID"])
            {
                return Json(new { success = false, message = "无删除权限" });
            }

            try
            {
                db.CarpoolInfo.Remove(carpoolInfo);
                await db.SaveChangesAsync();

                // 记录删除日志
                await LogOperation((int)Session["UserID"], OperationTypeEnum.删除拼车信息, $"删除拼车信息（ID：{id}）");

                return Json(new { success = true, message = "删除成功" });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = "删除失败：" + ex.Message });
            }
        }

        // 乘客发布拼车需求页面
        [HttpGet]
        [Authorize]
        public ActionResult PublishDemand()
        {
            return View();
        }

        // 处理拼车需求发布
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> PublishDemand(CarpoolDemand model)
        {
            if (ModelState.IsValid)
            {
                model.RequesterID = (int)Session["UserID"];
                model.PublishTime = DateTime.Now;
                model.Status = 1;
                db.CarpoolDemand.Add(model);
                await db.SaveChangesAsync();

                // 记录操作日志
                await LogOperation((int)Session["UserID"], OperationTypeEnum.发布拼车需求, $"发布拼车需求（ID：{model.DemandID}）");

                return RedirectToAction("Index", "Home");
            }
            return View(model);
        }

        // 申请加入拼车
        [Authorize]
        public async Task<ActionResult> Apply(int? id)
        {
            if (id == null) return HttpNotFound();

            // 验证拼车信息是否存在
            var carpool = db.CarpoolInfo.Find(id);
            if (carpool == null)
            {
                TempData["ErrorMessage"] = "拼车信息不存在";
                return RedirectToAction("Index", "Home");
            }

            // 验证是否重复申请
            var hasApplied = db.CarpoolApplication.Any(a =>
                a.ApplicantID == (int)Session["UserID"] && a.TargetID == id);
            if (hasApplied)
            {
                TempData["ErrorMessage"] = "您已申请过此拼车";
                return RedirectToAction("Detail", "Home", new { id });
            }

            var apply = new CarpoolApplication
            {
                ApplicantID = (int)Session["UserID"],
                TargetType = 1,
                TargetID = (int)id,
                ApplicationTime = DateTime.Now,
                Status = 1
            };
            db.CarpoolApplication.Add(apply);
            await db.SaveChangesAsync();

            await LogOperation((int)Session["UserID"], OperationTypeEnum.申请加入拼车, $"申请加入拼车（ID：{id}）");

            TempData["SuccessMessage"] = "申请已提交";
            return RedirectToAction("Detail", "Home", new { id });
        }

        // 关注拼车
        [Authorize]
        public async Task<ActionResult> Follow(int? id, int targetType)
        {
            if (id == null) return HttpNotFound();

            // 验证是否已关注
            var hasFollowed = db.CarpoolFollow.Any(f =>
                f.UserID == (int)Session["UserID"] && f.TargetID == id && f.TargetType == targetType);
            if (hasFollowed)
            {
                return Json(new { success = false, message = "已关注" });
            }

            var follow = new CarpoolFollow
            {
                UserID = (int)Session["UserID"],
                TargetType = (byte)targetType,
                TargetID = (int)id,
                FollowTime = DateTime.Now
            };
            db.CarpoolFollow.Add(follow);
            await db.SaveChangesAsync();

            await LogOperation((int)Session["UserID"], OperationTypeEnum.关注拼车, $"关注拼车（ID：{id}，类型：{targetType}）");

            return Json(new { success = true });
        }

        // 日志记录封装
        private async Task LogOperation(int userId, OperationTypeEnum operationType, string content)
        {
            // 限制日志内容长度，避免数据库字段溢出
            if (content.Length > 500)
            {
                content = content.Substring(0, 500);
            }

            db.SystemLog.Add(new SystemLog
            {
                UserID = userId,
                OperationType = (byte)operationType,
                OperationContent = content,
                OperationTime = DateTime.Now
            });
            await db.SaveChangesAsync();
        }
    }
}
